﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Cesave.Domain.Core;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Domain.PermisosModule.Resources;

namespace Cesave.Domain.PermisosModule.Contracts.Acls
{
	/// <summary>
	/// 
	/// </summary>
	public class AclService
		: IAclService
	{
		#region Private properties

		/// <summary>
		/// 
		/// </summary>
		private readonly IAclRepository _aclRepository;

		#endregion

		#region Constructor

		/// <summary>
		/// 
		/// </summary>
		/// <param name="aclRepository"></param>
		public AclService(IAclRepository aclRepository)
		{
			if (aclRepository == null)
				throw new ArgumentNullException("aclRepository", Messages.exception_DependenciesAreNotInitialized);
			_aclRepository = aclRepository;
		}

		#endregion

		#region IAclService Members

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public List<Acl> FindAllAcl()
		{
			return _aclRepository.GetAll()
				.OrderBy(acl => acl.AclId)
				.ToList();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="aclGuid"></param>
		/// <returns></returns>
		public Acl FindAclByGuid(Guid aclGuid)
		{
			if (aclGuid == Guid.Empty)
				throw new InvalidOperationException(Messages.exception_InvalidArgument);
			AclByGuidSpecification aclByGuidSpecification = new AclByGuidSpecification(aclGuid);
			return _aclRepository.GetBySpec(aclByGuidSpecification).FirstOrDefault();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="acl"></param>
		public void AddAcl(Acl acl)
		{
			if (acl == null)
				throw new ArgumentNullException("acl");
			IUnitOfWork unitOfWork = _aclRepository.StoreContext;
			_aclRepository.Add(acl);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.Commit();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="acl"></param>
		public void ChangeAcl(Acl acl)
		{
			if (acl == null)
				throw new ArgumentNullException("acl");
			IUnitOfWork unitOfWork = _aclRepository.StoreContext;
			_aclRepository.Modify(acl);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.Commit();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="acl"></param>
		public void DeleteAcl(Acl acl)
		{
			if (acl == null)
				throw new ArgumentNullException("acl");
			IUnitOfWork unitOfWork = _aclRepository.StoreContext;
			_aclRepository.Remove(acl);
			try
			{
				unitOfWork.Commit();
			}
			catch (OptimisticConcurrencyException)
			{
				unitOfWork.RollbackChanges();
				unitOfWork.Commit();
			}
		}

		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if (_aclRepository != null &&
				_aclRepository.StoreContext != null)
				_aclRepository.StoreContext.Dispose();
		}

		#endregion
	}
}
